package hasthi.container;

import hasthi.common.constants.HasthiConstants;

import java.net.URI;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.XmlObject;
import org.w3.x2003.x05.soapEnvelope.FaultDocument;
import org.xmlpull.v1.builder.XmlDocument;
import org.xmlpull.v1.builder.XmlElement;

import xsul.MLogger;
import xsul.soap.SoapUtil;
import xsul.ws_addressing.WsAddressing;
import xsul.ws_addressing.WsaInvoker;
import xsul.ws_addressing.WsaMessageInformationHeaders;
import xsul.ws_addressing.WsaRelatesTo;

public class SOAPUtils {
    private static Log log = LogFactory.getLog(HasthiConstants.LOGGER_NAME);
    public static boolean checkIfAsyncReplyRequired(WsaMessageInformationHeaders wsah) {
        boolean sendAsyncResp = false;
        String replyTo = null;
        // if the reply to field in the ws-addressing header is set not null and
        // is not
        // anonymous, then the client has requested async reply to the uri
        // denoted by the
        // replyto field

        if (wsah.getReplyTo() != null) {
            replyTo = wsah.getReplyTo().getAddress().toString();
            sendAsyncResp = !replyTo.equals(WsAddressing.URI_ROLE_ANONYMOUS
                    .toString());
        }
        if (!sendAsyncResp && wsah.getFaultTo() != null) {
            sendAsyncResp = !wsah.getFaultTo().getAddress().equals(
                    WsAddressing.URI_ROLE_ANONYMOUS);
        }
        if (sendAsyncResp) {
            log.info("Async response requested to " + replyTo);
        }
        return sendAsyncResp;
    }

    
    
    public static boolean isFaultMessage(XmlObject body){
        if(body instanceof FaultDocument || body instanceof org.xmlsoap.schemas.soap.envelope.FaultDocument){
            return true;
        }else{
            return false;
        }
    }
    
    
    public static void sendAsyncResponse(final SoapUtil soapFragrance,
            final XmlElement responseMessage, final WsaMessageInformationHeaders requestWsaHeaders,
            final boolean fault) {
        XmlDocument responseEnvelope = soapFragrance.wrapBodyContent(responseMessage);
        WsaMessageInformationHeaders responseWsaHeaders = new WsaMessageInformationHeaders(
                responseEnvelope);

        // if the response message is a fault message, send it to
        // faultTo instead of replyTo
        if (!fault) {
            responseWsaHeaders.explodeEndpointReference(requestWsaHeaders.getReplyTo());
        } else {
            if (requestWsaHeaders.getFaultTo() != null) {
                responseWsaHeaders.explodeEndpointReference(requestWsaHeaders.getFaultTo());
            } else {
                responseWsaHeaders.explodeEndpointReference(requestWsaHeaders.getReplyTo());
            }
        }

        URI messageId = requestWsaHeaders.getMessageId();
        if (messageId != null) {
            responseWsaHeaders.addRelatesTo(new WsaRelatesTo(requestWsaHeaders.getMessageId()));
        }
        WsaInvoker invoker = new WsaInvoker();
        invoker.setDefaultAction(requestWsaHeaders.getAction());
        invoker.sendXml(responseEnvelope);
    }
    
    /**
     * This will match for content types that will be regarded as REST in WSDL2.0.
     * This contains,
     * 1. application/xml
     * 2. application/x-www-form-urlencoded
     * 3. multipart/form-data
     * <p/>
     * If the request doesnot contain a content type; this will return true.
     *
     * @param contentType
     * @return Boolean
     */
//    public static boolean isRESTRequest(String contentType) {
//        if (contentType == null) {
//            return false;
//        }
//        return (contentType.indexOf(HTTPConstants.MEDIA_TYPE_APPLICATION_XML) > -1 ||
//                contentType.indexOf(HTTPConstants.MEDIA_TYPE_X_WWW_FORM) > -1 ||
//                contentType.indexOf(HTTPConstants.MEDIA_TYPE_MULTIPART_FORM_DATA) > -1);
//    }
}
